package character.action;

import gameobject.construct.Construct;
import character.AbstractCharacter;
import gameobject.item.RequiredItemHolder;
import mygame.DefaultValues;
import mygame.VoxelGrid;

public class BuildAction extends CharacterAction {

    public BuildAction() {}

    public BuildAction(Construct targetConstruct) {
	this.targetConstruct = targetConstruct;
    }

    public Construct getConstructToBuild() {
	return targetConstruct;
    }

    @Override
    protected boolean execute(AbstractCharacter performer) { //TODO make int return statuses instead of boolean (0=complete, 1=incomplete, 2+=failure codes...)
        if(targetConstruct.isBuilt()) { //if it's already been built
            return true;
        } else {
            float distanceToTarget = ActionUtility.getDistCharToConstruct(performer, targetConstruct);
            if(distanceToTarget < DefaultValues.ACTION_INTERACT_DISTANCE) {
		if(checkRequiredItemsToBuild(performer)) {
		    targetConstruct.modifyHitPoints(performer.getSettings().getBuildSpeed());
		    System.out.println("Building "+targetConstruct+"... "+targetConstruct.getHitPoints());
		    if(targetConstruct.isBuilt())
			return true;
		} else {
                    if(!tryTransferRequiredItemsToConstruct(performer))
                        System.out.println("Lacking required items to build "+targetConstruct);
		}
            } else {
                performer.queueActionFront(new MoveAction(VoxelGrid.getWorldLocation(targetConstruct.getBaseVoxelGridLocation()), DefaultValues.ACTION_INTERACT_DISTANCE));
            }
        }
        return false;
    }

    protected boolean checkRequiredItemsToBuild(AbstractCharacter performer) {
	if(performer.getInventory().containsRequiredItemsWithQuantities(targetConstruct.getRequiredItemsToBuild(), RequiredItemHolder.CHARACTER)
		&& targetConstruct.getInventory().containsRequiredItemsWithQuantities(targetConstruct.getRequiredItemsToBuild(), RequiredItemHolder.CONSTRUCT))
	    return true;
	else
	    return false;
    }
    
    /**
     * Attempts to transfer required build items from the character's inventory to the construct's.
     * Returns true if anything was transferred, false if nothing was transferred.
     */
    protected boolean tryTransferRequiredItemsToConstruct(AbstractCharacter performer) {
        return targetConstruct.getInventory().transferRequiredItems(performer.getInventory(), targetConstruct.getRequiredItemsToBuild(), RequiredItemHolder.CONSTRUCT);
    }
}
